package com.ruoyi.quartz.task;

import cn.hutool.core.util.ArrayUtil;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.sl.domain.*;
import com.ruoyi.sl.mapper.SlSaMapper;
import com.ruoyi.sl.service.*;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;

import java.util.*;


import static com.ruoyi.quartz.util.SlUtils.getYearNumber;
import static net.sf.jsqlparser.util.validation.metadata.NamedObject.user;

/**
 * 定时任务调度测试
 * 
 * @author ruoyi
 */
@Component("ryTask")
public class RyTask
{
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ISlRworkService slRworkService;
    @Autowired
    private ISlRworkRmemberService slRworkRmemberService;
    @Autowired
    private ISlApprenticeService slApprenticeService;
    @Autowired
    private ISlSpecialService slSpecialService;
    @Autowired
    private ISlFixedSalaryService slFixedSalaryService;
    @Autowired
    private ISlFullAttendanceService slFullAttendanceService;
    @Autowired
    private ISlSaService slSaService;
    @Autowired
    private ISlAttendanceService slAttendanceService;
    @Autowired
    private ISlOddjobService slOddjobService;
    @Autowired
    private ISlOddjobOmemberService slOddjobOmemberService;
    @Autowired
    private ISlOfcbaseService slOfcbaseService;
    @Autowired
    private ISlMonthOfcService slMonthOfcService;
    @Autowired
    private ISlWerrorService slWerrorService;
    @Autowired
    private ISlOfcperformanceService slOfcperformanceService;
    @Autowired
    private ISlOfcLeaveService slOfcLeaveService;

    @Autowired
    private ISlWsbaseService slWsbaseService;
    @Autowired
    private ISlWsMonthPayService slWsMonthPayService;
    @Autowired
    private ISlMonthWsService slMonthWsService;
    @Autowired
    private ISlWsperformanceService slWsperformanceService;
    @Autowired
    private ISlWsabsenceService slWsabsenceService;
    @Autowired
    private ISlSocialService slSocialService;
    @Autowired
    private ISlTeamMemberService slTeamMemberService;
    @Autowired
    private ISlDbinfoService slDbinfoService;
    @Autowired
    private ISlRfworkService slRfworkService;
    @Autowired
    private ISlWagesDayService slWagesDayService;
    @Autowired
    private ISlOddjobAttendanceService slOddjobAttendanceService;
    @Autowired
    private ISlDeductionService slDeductionService;
    @Autowired
    private ISlProcessService slProcessService;
    @Autowired
    private ISlOfcperbaseService slOfcperbaseService;
    @Autowired
    private ISlDmService slDmService;
    @Autowired
    private ISlSpecialAttendanceService slSpecialAttendanceService;
    @Autowired
    private ISysDeptService sysDeptService;

    /**
     * 指定日期后当月工资单禁止编辑
     * */
    @Transactional
    public void setMonthSalaryToHistory(){
        System.out.println("start------------月工资结算开始--------------");
            slMonthWsService.updateSlMonthWsToHistory();
            slMonthOfcService.updateSlMonthOfcToHistory();

        System.out.println("end------------月工资结算完成结束--------------");
    }


    /**
     * 车间月工资
     * */
    @Transactional
    public void countWsMonth()
    {
        System.out.println("start------------车间月工资计算开始--------------");

        //职级7初级8中级9高级学徒
        Long[] apprenticeIds = {new Long(7),new Long(8),new Long(9)};
        //获取当前日期上一个月满勤信息
        Map<String,Object> map = new HashMap<>();
        Calendar calendar = Calendar.getInstance();
        int month = calendar.get(Calendar.MONTH)+1;
        String formattedMonth = String.format("%02d",month);
        int year = calendar.get(Calendar.YEAR);
        map.put("strYear",String.valueOf(year));
        map.put("strMonth",formattedMonth);
        SlFullAttendance slFullAttendance = slFullAttendanceService.selectSlFullAttendanceByMonth(map);

        //删除工资记录
        slMonthWsService.deleteSlMonthWsByDate(slFullAttendance.getYear(),slFullAttendance.getMonth());

        //月份工资开始日期
        Date startDate = slFullAttendance.getStartDate();
        //月份工资结束日期
        Date endDate = slFullAttendance.getEndDate();
        //满勤天
        BigDecimal fullDay = slFullAttendance.getFullAttendance();
        //高温补贴
        BigDecimal highTemperature = slFullAttendance.getHighTemperatureSubsidy();
        //查询对应月份所有人员的工资
        List<SlWagesDay> slWagesDayList = slWagesDayService.selectTotalWagesDayListByDate(startDate,endDate);
        if (StringUtils.isNotEmpty(slWagesDayList)){

            for (SlWagesDay slWagesDay : slWagesDayList) {

                if(StringUtils.isNull(slWagesDay)){
                    continue;
                }

                SysUser sysUser = userService.selectUserByUserName(slWagesDay.getUserName());
                //获取该人员所在部门是否有自己的考勤规则
                String tmpYear = String.valueOf(year);

                SlSpecialAttendance slSpecialAttendance = slSpecialAttendanceService.selectSlSpecialAttendanceByDeptId(sysUser.getDeptId(),tmpYear,formattedMonth);
                if(StringUtils.isNull(slSpecialAttendance)){
                    SysDept sysDpet =  sysDeptService.selectDeptById(sysUser.getDeptId());
                    String[] arrDeptIds = sysDpet.getAncestors().split(",");
                    int i = arrDeptIds.length - 1;
                    while(StringUtils.isNull(slSpecialAttendance) && i>=0){
                        slSpecialAttendance = slSpecialAttendanceService.selectSlSpecialAttendanceByDeptId(Long.parseLong(arrDeptIds[i]),tmpYear,formattedMonth);
                        i--;
                    }
                    if(StringUtils.isNotNull(slSpecialAttendance)){
                        //月份工资开始日期
                         startDate = slSpecialAttendance.getStartDate();
                        //月份工资结束日期
                         endDate = slSpecialAttendance.getEndDate();
                        //满勤天
                         fullDay = slSpecialAttendance.getFullAttendance();
                        //高温补贴
                         highTemperature = slSpecialAttendance.getHighTemperatureSubsidy();
                    }
                }
                //-------------------基本工资----------------------
                SlMonthWs slMonthWs = new SlMonthWs();
                slMonthWs.setUserName(slWagesDay.getUserName());
                slMonthWs.setUserNick(slWagesDay.getNickName());
                slMonthWs.setWsmpayYear(slFullAttendance.getYear());
                slMonthWs.setWsmpayMonth(slFullAttendance.getMonth());
                slMonthWs.setWsmpayDate(DateUtils.dateTime("yyyy-MM-dd",slFullAttendance.getYear()+"-"+slFullAttendance.getMonth()+"-01"));
                slMonthWs.setWsmpayStart(startDate);
                slMonthWs.setWsmpayEnd(endDate);

                //--满勤天数
                slMonthWs.setFullDay(fullDay);
                //--高温补贴
                slMonthWs.setHighTemperature(highTemperature);
                //工资
                BigDecimal salary = StringUtils.nvl(slWagesDay.getProWages(),BigDecimal.ZERO);
                //基础系数
                //个人绩效比例
                BigDecimal personalPerformance = BigDecimal.ZERO;
                //部门绩效比例
                BigDecimal deptPerformance = BigDecimal.ZERO;
                //工龄工资系数
                BigDecimal workingAgeSubsidy = BigDecimal.ZERO;
                //餐补系数
                BigDecimal mealAllowanceSubsidy = BigDecimal.ZERO;
                //早班补助系数
                BigDecimal earlyShiftSubsidy = BigDecimal.ZERO;
                //晚班补助系数
                BigDecimal nightShiftSubsidy = BigDecimal.ZERO;
                //考勤补贴
                BigDecimal defaultSubsidy = BigDecimal.ZERO;
                //其他补贴
                BigDecimal otherSubsidy = BigDecimal.ZERO;
                 //公积金
                BigDecimal providentFund = BigDecimal.ZERO;
                //社保
                BigDecimal socialSecurity = BigDecimal.ZERO;
                //代扣税
                BigDecimal taxDeductiond = BigDecimal.ZERO;

                if(slWagesDay.getSsmId()==1 && !ArrayUtil.contains(apprenticeIds, slWagesDay.getLevelId())){
                    //固定工资配置
                    SlOfcperbase slOfcperbase = slOfcperbaseService.selectOnlySlOfcperbaseByUerName(slWagesDay.getUserName());
                    if (StringUtils.isNotNull(slOfcperbase)){
                        salary = slOfcperbase.getDefaultWages();
                        personalPerformance = slOfcperbase.getPersonalPerformance();
                        deptPerformance = slOfcperbase.getDeptPerformance();
                        workingAgeSubsidy = slOfcperbase.getWorkingAgeSubsidy();
                        mealAllowanceSubsidy = slOfcperbase.getMealAllowance();
                        earlyShiftSubsidy = slOfcperbase.getEarlyShiftSubsidy();
                        nightShiftSubsidy = slOfcperbase.getNightShiftSubsidy();
                        defaultSubsidy = slOfcperbase.getDefaultSubsidy();
                        otherSubsidy = slOfcperbase.getOtherSubsidy();
                        providentFund = slOfcperbase.getProvidentFund();
                        socialSecurity = slOfcperbase.getSocialSecurity();
                        taxDeductiond = slOfcperbase.getTaxDeductiond();
                    }
                }else{
                    //非固定工资
                    SlSocial slSocial = slSocialService.selectOnlySlSocialByUserName(slWagesDay.getUserName());
                    if (StringUtils.isNotNull(slSocial)){
                        workingAgeSubsidy = slSocial.getWorkingAgeSubsidy();
                        mealAllowanceSubsidy = slSocial.getMealAllowance();
                        earlyShiftSubsidy = slSocial.getEarlyShiftSubsidy();
                        nightShiftSubsidy = slSocial.getNightShiftSubsidy();
                        defaultSubsidy = slSocial.getDefaultSubsidy();
                        otherSubsidy = slSocial.getOtherSubsidy();
                        providentFund = slSocial.getProvidentFund();
                        socialSecurity = slSocial.getSocialSecurity();
                        taxDeductiond = slSocial.getTaxDeductiond();
                    }
                }
                //非正式员工无绩效
                if("N".equals(sysUser.getIsFormalworker())){
                    deptPerformance =  BigDecimal.ZERO;
                    personalPerformance = BigDecimal.ZERO;
                }

                //发薪比例(转化小数)
                BigDecimal payPerformance = BigDecimal.valueOf(100).subtract(personalPerformance).subtract(deptPerformance).divide(BigDecimal.valueOf(100)).setScale(2,RoundingMode.DOWN);
                //绩效比例(转换小数)
                BigDecimal performance = personalPerformance.add(deptPerformance).divide(BigDecimal.valueOf(100)).setScale(2,RoundingMode.DOWN);

                //个人绩效
                slMonthWs.setPersonalPerformance(personalPerformance);
                //部门绩效
                slMonthWs.setDeptPerformance(deptPerformance);
                //底薪
                slMonthWs.setBasicSalary(salary);
                //考勤补贴
                slMonthWs.setWorkAllowance(defaultSubsidy);
                //其他补贴
                slMonthWs.setOtherSubsidy(otherSubsidy);
                //审核扣款
                BigDecimal dmAmount = BigDecimal.ZERO;
                SlDeduction slDeduction = new SlDeduction();
                slDeduction.setMemberUser(slWagesDay.getUserName());
                slDeduction.setIsSettle("1");
                List<SlDeduction> slDeductionList = slDeductionService.selectSlDeductionList(slDeduction);
                if(StringUtils.isNotEmpty(slDeductionList)){
                    Set<Long> dmIds = new HashSet<>();
                    for (SlDeduction deduction:slDeductionList) {
                        dmAmount = dmAmount.add(deduction.getDmAmount());
                        //标记已结算,避免重复扣款
                        deduction.setIsSettle("0");
                        slDeductionService.updateSlDeduction(deduction);
                        dmIds.add(deduction.getDmId());
                    }
                    for (Long dmId : dmIds) {
                        slDmService.updateSlDmIsSettle(dmId);
                    }
                }
                slMonthWs.setDmAmount(dmAmount);
                //工资扣罚款
                salary = salary.subtract(dmAmount);
                //全面薪酬
                BigDecimal totalReward = salary.add(defaultSubsidy);
                slMonthWs.setTotalReward(totalReward);
                //每月固定（扣绩效后）
                slMonthWs.setFixedSalary(totalReward.multiply(payPerformance).setScale(2,RoundingMode.DOWN));
                //出勤天数
                BigDecimal attendanceDay = StringUtils.nvl(slWagesDay.getProDay(),BigDecimal.ZERO);
                slMonthWs.setAttendanceDay(attendanceDay);
                //绩效出勤天数
                BigDecimal performanceDay = attendanceDay;
                if(attendanceDay.compareTo(fullDay) > 0){
                    performanceDay = fullDay;
                }
                //缺勤天数
                BigDecimal absenceDay = fullDay.subtract(performanceDay);
                slMonthWs.setAbsenceDay(absenceDay);
                //出勤固定
                BigDecimal attendancePay = BigDecimal.ZERO;
                if(absenceDay.compareTo(BigDecimal.ZERO)!=0){
                    attendancePay = slMonthWs.getFixedSalary().multiply(attendanceDay).divide(fullDay,2,RoundingMode.DOWN).setScale(2,RoundingMode.DOWN);
                }else {
                    attendancePay = slMonthWs.getFixedSalary();
                }
                slMonthWs.setAttendancePay(attendancePay);
                //工龄（当月开始日期-入职日期）
                Date entryDate = sysUser.getEntryDate();
                int workingAge = getYearNumber(entryDate,startDate);
                slMonthWs.setWorkingAge(workingAge);
                //工龄工资基数
                //BigDecimal ageBase = slWsbase.getWorkingAgeSubsidy();
                slMonthWs.setAgeBase(workingAgeSubsidy);
                //工龄工资 工龄工资*出勤天数/满勤天数
                BigDecimal ageAllpay = workingAgeSubsidy.multiply(BigDecimal.valueOf(workingAge)).multiply(performanceDay).divide(fullDay,2,RoundingMode.DOWN).setScale(2,RoundingMode.DOWN);
                slMonthWs.setAgeAllpay(ageAllpay);
                //工龄工资
                //BigDecimal agePay = ageAllpay.multiply(payPerformance).setScale(2, RoundingMode.DOWN);
                //slMonthWs.setAgePay(agePay);
                //餐补基数
                slMonthWs.setMealBase(mealAllowanceSubsidy);
                //餐补(基数x出勤天数) 当日出勤>-0.5有餐补
                BigDecimal mealAllowanceCount = slWagesDayService.selectMealAllowanceCountByUserAndDate(startDate,endDate,slWagesDay.getUserName());
                if(mealAllowanceCount.compareTo(fullDay)>0){
                    mealAllowanceCount = fullDay;
                }
                BigDecimal mealAllowance = mealAllowanceSubsidy.multiply(mealAllowanceCount).setScale(2, RoundingMode.DOWN);
                slMonthWs.setMealAllowance(mealAllowance);
                //早班次数
                Map<String,Object> params = new HashMap<>();
                params.put("rmemberBz","0");
                params.put("rmemberUser",slWagesDay.getUserName());
                params.put("startDate",startDate);
                params.put("endDate",endDate);
                int earlyNum = slRworkRmemberService.selectBzCountByUserAndDate(params);
                slMonthWs.setEarlyNum(earlyNum);
                //早班补助基数
                slMonthWs.setEarlyBase(earlyShiftSubsidy);
                //早班补助(基数x次数)
                slMonthWs.setEarlyShift(earlyShiftSubsidy.multiply(BigDecimal.valueOf(earlyNum)).setScale(2,RoundingMode.DOWN));
                //晚班次数
                params.put("rmemberBz","1");
                params.put("rmemberUser",slWagesDay.getUserName());
                params.put("startDate",startDate);
                params.put("endDate",endDate);
                int nightNum = slRworkRmemberService.selectBzCountByUserAndDate(params);
                slMonthWs.setNightNum(nightNum);
                //晚班补助基数
                slMonthWs.setNightBase(nightShiftSubsidy);
                //晚班补助(基数x次数)
                slMonthWs.setNightShift(nightShiftSubsidy.multiply(BigDecimal.valueOf(nightNum)).setScale(2,RoundingMode.DOWN));
                //加班补助（含绩效）
                slMonthWs.setOvertimeAllallowance(BigDecimal.ZERO);
                //加班补助
                //slMonthWs.setOvertimeAllowance(BigDecimal.ZERO);

                //应发工资=出勤固定+出勤工龄工资+餐补+高温补贴+早班补助+晚班补助+加班补助
                BigDecimal wagePayable = attendancePay.add(ageAllpay).add(mealAllowance).add(highTemperature).add(slMonthWs.getEarlyShift()).add(slMonthWs.getNightShift()).add(slMonthWs.getOvertimeAllallowance()).add(otherSubsidy).setScale(2,RoundingMode.DOWN);
                //BigDecimal wagePayable = salary.add(ageAllpay).add(slMonthWs.getEarlyShift()).add(slMonthWs.getNightShift()).add(slMonthWs.getOvertimeAllallowance()).multiply(payPerformance).add(mealAllowance).add(highTemperature).setScale(2, BigDecimal.ROUND_DOWN);
                slMonthWs.setWagePayable(wagePayable);
                //社保、公积金、代扣税
                slMonthWs.setSocialSecurity(socialSecurity);
                slMonthWs.setProvidentFund(providentFund);
                slMonthWs.setTaxDeduction(taxDeductiond);

                //每月实发=应发工资-公积金-社保-代扣税
                BigDecimal netSalary = wagePayable.subtract(slMonthWs.getProvidentFund()).subtract(slMonthWs.getSocialSecurity()).subtract(slMonthWs.getTaxDeduction()).setScale(2, RoundingMode.DOWN);
                slMonthWs.setNetSalary(netSalary);
                slMonthWsService.insertSlMonthWs(slMonthWs);
                //--------------绩效-------------------
                if (personalPerformance.compareTo(BigDecimal.ZERO)!=0 || deptPerformance.compareTo(BigDecimal.ZERO)!=0){
                    SlWsperformance slWsperformance = new SlWsperformance();
                    slWsperformance.setMpayId(slMonthWs.getWsmpayId());
                    slWsperformance.setPerformanceYear(slFullAttendance.getYear());
                    slWsperformance.setPerformanceMonth(slFullAttendance.getMonth());
                    slWsperformance.setPerformanceUser(slMonthWs.getUserName());
                    slWsperformance.setPerformanceNick(slMonthWs.getUserNick());
                    //绩效天数
                    slWsperformance.setPerformanceDay(performanceDay);
                    //绩效缺勤天数
                    BigDecimal perAbsenceDay = absenceDay;
                    if(absenceDay.compareTo(BigDecimal.valueOf(2))<=0){
                        perAbsenceDay = BigDecimal.ZERO;
                    }
                    slWsperformance.setPerformanceDay(perAbsenceDay);
                    //绩效基数
                    BigDecimal performanceBase = slMonthWs.getTotalReward().add(ageAllpay).add(slMonthWs.getEarlyShift()).add(slMonthWs.getNightShift()).add(slMonthWs.getOvertimeAllallowance());
                    performanceBase = performanceBase.multiply(performance).setScale(2, RoundingMode.DOWN);
                    if (perAbsenceDay.compareTo(BigDecimal.valueOf(3))>=0){
                        performanceBase = performanceBase.multiply(performanceDay).divide(fullDay,2, RoundingMode.DOWN).setScale(2, RoundingMode.DOWN);
                    }
                    slWsperformance.setPerformanceBase(performanceBase);
                    //扣发出勤绩效
                    SlWsabsence slWscabsence = slWsabsenceService.selectSlWsabsenceByAbsenceDay(perAbsenceDay);
                    BigDecimal wsPerformance = BigDecimal.ZERO;
                    if (StringUtils.isNotNull(slWscabsence)){
                        wsPerformance = performanceBase.multiply(slWscabsence.getAbsencePerformance().divide(BigDecimal.valueOf(100),2, RoundingMode.DOWN)).setScale(2, RoundingMode.DOWN);
                    }
                    slWsperformance.setPerformanceDeduction(wsPerformance);
                    //工作绩效(工作绩效)
                    BigDecimal deduction = BigDecimal.ZERO;
                    List<SlWerror> slWerrorList = slWerrorService.selectSlWerrorByUserName(slMonthWs.getUserName());
                    if (StringUtils.isNotEmpty(slWerrorList)){
                        for (SlWerror slWerror : slWerrorList) {
                            deduction = deduction.add(slWerror.getWerrorFine());
                            //记录该工作绩效被哪个工资单扣减了，避免重复扣减
                            slWerror.setMpayId(slMonthWs.getWsmpayId());
                        }
                    }
                    slWsperformance.setDeduction(deduction);
                    //剩余绩效
                    BigDecimal performanceResidue = performanceBase.subtract(wsPerformance).subtract(deduction);
                    slWsperformance.setPerformanceResidue(performanceResidue);

                    slWsperformanceService.insertSlWsperformance(slWsperformance);

                    //更新工作绩效
                    for (SlWerror slWerror : slWerrorList) {
                        slWerrorService.updateSlWerror(slWerror);
                    }
                }


            }

        }


        System.out.println("end------------车间月工资计算结束--------------");

    }


    /**
     * 行政固定工资
     * */
    @Transactional
    public void countOfcMonth(Long deptId)
    {
        System.out.println("start------------行政月工资计算开始--------------");

        //固定工资
        BigDecimal basicSalary = BigDecimal.ZERO;
        //个人绩效比例
        BigDecimal personalPerformance = BigDecimal.ZERO;
        //部门绩效比例
        BigDecimal deptPerformance = BigDecimal.ZERO;
        //工龄工资系数
        BigDecimal workingAgeSubsidy = BigDecimal.ZERO;
        //餐补系数
        BigDecimal mealAllowanceSubsidy = BigDecimal.ZERO;
        //早班补助系数
        BigDecimal earlyShiftSubsidy = BigDecimal.ZERO;
        //晚班补助系数
        BigDecimal nightShiftSubsidy = BigDecimal.ZERO;
        //考勤补贴
        BigDecimal workAllowance = BigDecimal.ZERO;
        //其他补贴
        BigDecimal otherSubsidy = BigDecimal.ZERO;
        //公积金
        BigDecimal providentFund = BigDecimal.ZERO;
        //社保
        BigDecimal socialSecurity = BigDecimal.ZERO;
        //代扣税
        BigDecimal taxDeductiond = BigDecimal.ZERO;

        //获取对应月份的满勤信息
        Map<String,Object> map = new HashMap<>();
        Calendar calendar = Calendar.getInstance();
        int month = calendar.get(Calendar.MONTH);
        String formattedMonth = String.format("%02d",month);
        int year = calendar.get(Calendar.YEAR);
        map.put("strYear",String.valueOf(year));
        map.put("strMonth",formattedMonth);
        SlFullAttendance slFullAttendance = slFullAttendanceService.selectSlFullAttendanceByMonth(map);

        //删除工资记录
        slMonthOfcService.deleteSlMonthOfcByDate(slFullAttendance.getYear(),slFullAttendance.getMonth());

        //获取非车间部门成员
        List<SysUser> listUser = userService.selectUserByNotDept(deptId);
        for (SysUser user : listUser) {

            SlOfcperbase slOfcperbase = slOfcperbaseService.selectOnlySlOfcperbaseByUerName(user.getUserName());
            if (StringUtils.isNotNull(slOfcperbase)){
                basicSalary = slOfcperbase.getDefaultWages();
                personalPerformance = slOfcperbase.getPersonalPerformance();
                deptPerformance = slOfcperbase.getDeptPerformance();
                workingAgeSubsidy = slOfcperbase.getWorkingAgeSubsidy();
                mealAllowanceSubsidy = slOfcperbase.getMealAllowance();
                earlyShiftSubsidy = slOfcperbase.getEarlyShiftSubsidy();
                nightShiftSubsidy = slOfcperbase.getNightShiftSubsidy();
                workAllowance = slOfcperbase.getDefaultSubsidy();
                otherSubsidy = slOfcperbase.getOtherSubsidy();
                providentFund = slOfcperbase.getProvidentFund();
                socialSecurity = slOfcperbase.getSocialSecurity();
                taxDeductiond = slOfcperbase.getTaxDeductiond();
            }

            //非正式员工无绩效
            if("N".equals(user.getIsFormalworker())){
                personalPerformance = BigDecimal.ZERO;
                deptPerformance = BigDecimal.ZERO;
            }

            //发薪比例(转化小数)
            BigDecimal payPerformance = (BigDecimal.valueOf(100).subtract(personalPerformance).subtract(deptPerformance)).divide(BigDecimal.valueOf(100)).setScale(2,RoundingMode.DOWN);
            //绩效比例(转换小数)
            BigDecimal performance = personalPerformance.add(deptPerformance).divide(BigDecimal.valueOf(100)).setScale(2,RoundingMode.DOWN);

            //-------------------基本工资----------------------
            SlMonthOfc slMonthOfc = new SlMonthOfc();
            slMonthOfc.setUserName(user.getUserName());
            slMonthOfc.setUserNick(user.getNickName());
            slMonthOfc.setDeptId(user.getDeptId());
            slMonthOfc.setOfcmpayYear(slFullAttendance.getYear());
            slMonthOfc.setOfcmpayMonth(slFullAttendance.getMonth());
            slMonthOfc.setOfcmpayDate(DateUtils.dateTime("yyyy-MM-dd",slFullAttendance.getYear()+"-"+slFullAttendance.getMonth()+"-01"));

            //底薪
            slMonthOfc.setBasicSalary(basicSalary);
            //考勤补贴
            slMonthOfc.setWorkAllowance(workAllowance);
            //其他补贴
            slMonthOfc.setOtherSubsidy(otherSubsidy);
            //岗薪
            BigDecimal postPay = BigDecimal.ZERO;
            if(StringUtils.isNotNull(user.getPostn())){
                postPay = user.getPostn().getPostnPay();
            }
            slMonthOfc.setPostPay(postPay);
            //职薪
            BigDecimal gradePay = BigDecimal.ZERO;
            if(StringUtils.isNotNull(user.getGrade())){
                gradePay = user.getGrade().getGradePay();
            }
            slMonthOfc.setGradePay(gradePay);
            //学历
            BigDecimal educationPay = BigDecimal.ZERO;
            if(StringUtils.isNotNull(user.getEducation())){
                educationPay = user.getEducation().getEducationPay();
            }
            slMonthOfc.setEducationPay(educationPay);
            //个人绩效比例
            slMonthOfc.setPersonalPerformance(personalPerformance);
            //部门绩效比例
            slMonthOfc.setDeptPerformance(deptPerformance);
            //全面薪酬=底薪+岗薪+职称+考勤补贴+学历
            BigDecimal totalReward = basicSalary.add(postPay).add(gradePay).add(workAllowance).add(educationPay);
            slMonthOfc.setTotalReward(totalReward);
            //每月固定=（底薪+岗薪+职称+考勤补贴+学历）*（1-个人绩效-部门绩效）
            BigDecimal fixedSalary = totalReward.multiply(payPerformance).setScale(2,RoundingMode.DOWN);
            slMonthOfc.setFixedSalary(fixedSalary);
            //满勤天数
            BigDecimal fullDay = slFullAttendance.getFullAttendance();
            slMonthOfc.setFullDay(fullDay);
            //出勤天数(默认满出勤)
            slMonthOfc.setAttendanceDay(fullDay);
            //缺勤天数
            slMonthOfc.setAbsenceDay(BigDecimal.ZERO);
            //出勤固定
            slMonthOfc.setAttendancePay(fixedSalary);
            //月份开始日期
            slMonthOfc.setOfcmpayStart(slFullAttendance.getStartDate());
            //结束日期
            slMonthOfc.setOfcmpayEnd(slFullAttendance.getEndDate());
            //工龄（当月开始日期-入职日期），办公室没工龄工资
            Date entryDate = user.getEntryDate();
            int workingAge = getYearNumber(entryDate,slFullAttendance.getStartDate());
            slMonthOfc.setWorkingAge(workingAge);
            //工龄工资基数
            //BigDecimal ageBase = slOfcbase.getWorkingAgeSubsidy();
            slMonthOfc.setAgeBase(workingAgeSubsidy);
            //工龄工资
            BigDecimal ageAllpay = workingAgeSubsidy.multiply(BigDecimal.valueOf(workingAge)).setScale(2,RoundingMode.DOWN);
            slMonthOfc.setAgeAllpay(ageAllpay);
            //工龄工资
            //BigDecimal agePay = ageAllpay.multiply(payPerformance).setScale(2,BigDecimal.ROUND_DOWN);
            //slMonthOfc.setAgePay(agePay);
            //餐补基数
            slMonthOfc.setMealBase(mealAllowanceSubsidy);
            //餐补(基数x出勤天数)
            BigDecimal mealAllowance = mealAllowanceSubsidy.multiply(fullDay).setScale(2,RoundingMode.DOWN);
            slMonthOfc.setMealAllowance(mealAllowance);
            //高温补贴
            BigDecimal highTemperature = slFullAttendance.getHighTemperatureSubsidy();
            slMonthOfc.setHighTemperature(highTemperature);
            //早班次数
            slMonthOfc.setEarlyNum(0);
            //早班补助基数
            slMonthOfc.setEarlyBase(earlyShiftSubsidy);
            //早班补助(基数x次数)
            slMonthOfc.setEarlyShift(BigDecimal.ZERO);
            //晚班次数
            slMonthOfc.setNightNum(0);
            //晚班补助基数
            slMonthOfc.setNightBase(nightShiftSubsidy);
            //晚班补助(基数x次数)
            slMonthOfc.setNightShift(BigDecimal.ZERO);
            //加班补助（含绩效）
            slMonthOfc.setOvertimeAllallowance(BigDecimal.ZERO);
            //加班补助
            //slMonthOfc.setOvertimeAllowance(BigDecimal.ZERO);
            //应发工资=产假工资+工伤假工资+病假工资+出勤固定+出勤工龄工资+餐补+高温补贴+早班补助+晚班补助+加班补助
            BigDecimal wagePayable = slMonthOfc.getAttendancePay().add(ageAllpay).add(mealAllowance).add(highTemperature).add(slMonthOfc.getEarlyShift()).add(slMonthOfc.getNightShift()).add(slMonthOfc.getOvertimeAllallowance()).add(slMonthOfc.getOtherSubsidy()).setScale(2,RoundingMode.DOWN);
            //BigDecimal wagePayable = fixedSalary.add(ageAllpay).add(mealAllowance);
            slMonthOfc.setWagePayable(wagePayable);
            //社保、公积金、代扣税
            slMonthOfc.setSocialSecurity(socialSecurity);
            slMonthOfc.setProvidentFund(providentFund);
            slMonthOfc.setTaxDeduction(taxDeductiond);
            //实发
            BigDecimal netSalary = wagePayable.subtract(socialSecurity).subtract(providentFund).subtract(taxDeductiond);
            slMonthOfc.setNetSalary(netSalary);
            //创建记录
            slMonthOfcService.insertSlMonthOfc(slMonthOfc);
            //-------------------请假工资----------------------
            SlOfcLeave slOfcLeave = new SlOfcLeave();
            slOfcLeave.setOfcmpayId(slMonthOfc.getOfcmpayId());
            slOfcLeave.setLeaveAbsenceNum(BigDecimal.ZERO);
            slOfcLeave.setInjuryLeaveNum(BigDecimal.ZERO);
            slOfcLeave.setInjuryLeavePay(BigDecimal.ZERO);
            slOfcLeave.setSickLeaveNum(BigDecimal.ZERO);
            slOfcLeave.setSickLeavePay(BigDecimal.ZERO);
            slOfcLeave.setMarriageLeaveNum(BigDecimal.ZERO);
            slOfcLeave.setMarriageLeavePay(BigDecimal.ZERO);
            slOfcLeave.setBereavementLeaveNum(BigDecimal.ZERO);
            slOfcLeave.setBereavementLeavePay(BigDecimal.ZERO);
            slOfcLeave.setMaternityLeaveNum(BigDecimal.ZERO);
            slOfcLeave.setMaternityLeavePay(BigDecimal.ZERO);
            slOfcLeave.setPaternityLeaveNum(BigDecimal.ZERO);
            slOfcLeave.setPaternityLeavePay(BigDecimal.ZERO);
            slOfcLeaveService.insertSlOfcLeave(slOfcLeave);
            //-------------------绩效工资----------------------
            if (personalPerformance.compareTo(BigDecimal.ZERO)!=0 || deptPerformance.compareTo(BigDecimal.ZERO)!=0){
                SlOfcperformance slOfcperformance = new SlOfcperformance();
                slOfcperformance.setOfcmpayId(slMonthOfc.getOfcmpayId());
                slOfcperformance.setPerformanceYear(slFullAttendance.getYear());
                slOfcperformance.setPerformanceMonth(slFullAttendance.getMonth());
                slOfcperformance.setPerformanceUser(user.getUserName());
                slOfcperformance.setPerformanceNick(user.getNickName());
                //绩效天数默认是满勤天数
                BigDecimal performanceDay = fullDay;
                slOfcperformance.setPerformanceDay(performanceDay);
                //缺勤天数
                BigDecimal absenceDay = BigDecimal.ZERO;
                slOfcperformance.setAbsenceDay(absenceDay);
                //绩效基数  薪水*绩效比例*出勤/满勤
                BigDecimal performanceBase = (totalReward.multiply(performance).multiply(performanceDay).divide(fullDay,2, RoundingMode.DOWN)).setScale(2, RoundingMode.DOWN);
                slOfcperformance.setPerformanceBase(performanceBase);
                //扣发
                BigDecimal performanceDeduction = BigDecimal.ZERO;
                slOfcperformance.setPerformanceDeduction(performanceDeduction);
                //工作绩效
                BigDecimal deduction = BigDecimal.ZERO;
                List<SlWerror> slWerrorList = slWerrorService.selectSlWerrorByUserName(user.getUserName());
                if (StringUtils.isNotEmpty(slWerrorList)){
                    for (SlWerror slWerror : slWerrorList) {
                        deduction = deduction.add(slWerror.getWerrorFine());
                        //记录该工作绩效被哪个工资单扣减了，避免重复扣减
                        slWerror.setMpayId(slMonthOfc.getOfcmpayId());
                    }
                }
                slOfcperformance.setDeduction(deduction);
                //剩余绩效
                BigDecimal performanceResidue = performanceBase.subtract(performanceDeduction).subtract(deduction);
                slOfcperformance.setPerformanceResidue(performanceResidue);

                slOfcperformanceService.insertSlOfcperformance(slOfcperformance);

                //更新工作绩效
                for (SlWerror slWerror : slWerrorList) {
                    slWerrorService.updateSlWerror(slWerror);
                }
            }

        }

        System.out.println("end------------行政月工资计算结束--------------");

    }

    /**
     * 车间日工资
     * */
    @Transactional
    public void countWsDay()
    {
        System.out.println("start------------车间日工资计算开始--------------");
        //职级7初级8中级9高级学徒
        Long[] apprenticeIds = {new Long(7),new Long(8),new Long(9)};
        //1个出勤天=多少小时
        BigDecimal workHours = BigDecimal.valueOf(10);
        //车间薪资基础配置
        SlWsbase slWsbase = slWsbaseService.selectSlWsbaseByWsbaseId(1L);
        //特殊系数人员最后计算
        List<SlAttendance> lastAttendance = new ArrayList<>();
        //原皮库所有成员
        List<String> ypkUsers = new ArrayList<>();
        List<SlTeamMember> teamMemberList = slTeamMemberService.selectSlTeamMemberListByTeamCode("ypk");
        if(StringUtils.isNotEmpty(teamMemberList)){
            for (SlTeamMember teamMember:teamMemberList) {
                ypkUsers.add(teamMember.getUserName());
            }
        }
        //记录原皮库的工作日期
        Set<Date> ypkDateList = new HashSet();

        //指定日期所有复核通过的计件报工单
        Date tmpDate = DateUtils.dateTime("yyyy-MM-dd",DateUtils.getDate());
        List<SlRfwork> list = slRfworkService.selectAllApprovedSlRfworkListByDate("0",tmpDate);

        for (SlRfwork rfwork : list) {

            //根据出勤记录创建当日对应报工单工资记录
            List<SlAttendance> slAttendanceList = slAttendanceService.selectAllSlAttendanceByRfworkId(rfwork.getRfworkId());
            BigDecimal attendanceDay = BigDecimal.ZERO; //总出勤结算天数
            if (StringUtils.isNotEmpty(slAttendanceList)) {
                //计算每个人的结算比例
                for (SlAttendance slAttendance : slAttendanceList) {
                    BigDecimal tmpSettlementDay = slAttendance.getAttendanceDay();  //出勤结算天数
                    BigDecimal tmpCoefficient = BigDecimal.valueOf(1);  //工资系数
                    BigDecimal tmpScale = BigDecimal.valueOf(1);    //出勤结算比例

                    if (ArrayUtil.contains(apprenticeIds, slAttendance.getLevelId())) {
                        //学徒的按比例转换结算天数
                        SlApprentice slApprentice = new SlApprentice();
                        slApprentice.setModuleId(rfwork.getModuleId());
                        slApprentice.setLevelId(slAttendance.getLevelId());
                        slApprentice = slApprenticeService.selectSlApprenticeByModuleAndLevel(slApprentice);
                        if (StringUtils.isNotNull(slApprentice)){
                            tmpScale = slApprentice.getApprenticeDay();
                            tmpSettlementDay = tmpSettlementDay.multiply(tmpScale).setScale(2,RoundingMode.DOWN);
                        }
                    }else {
                        //特殊系数结算比例
                        Long ssmId = slAttendance.getSsmId();
                        SlSpecial slSpecial = slSpecialService.selectSlSpecialByUserName(slAttendance.getUserName());
                        if (StringUtils.isNotNull(slSpecial)){
                            if(ssmId==2 || ssmId==4){
                                if("1".equals(slSpecial.getIsProduce())){
                                    tmpSettlementDay = BigDecimal.ZERO;
                                    tmpScale = BigDecimal.ZERO;
                                }else{
                                    tmpSettlementDay = tmpSettlementDay.multiply(slSpecial.getSsScale()).setScale(2,RoundingMode.DOWN);
                                    tmpScale = slSpecial.getSsScale();
                                }
                                tmpCoefficient = slSpecial.getSsRatio();
                            }
                        }
                    }

                    slAttendance.setScale(tmpScale);
                    slAttendanceService.updateSlAttendance(slAttendance);

                    attendanceDay = attendanceDay.add(tmpSettlementDay);

                    //特殊系数存起来
                    if(slAttendance.getSsmId()==4){
                        lastAttendance.add(slAttendance);
                    }else{
                        //当日工资记录
                        SlWagesDay slWagesDay = new SlWagesDay();
                        slWagesDay.setLevelId(slAttendance.getLevelId());
                        slWagesDay.setSsmId(slAttendance.getSsmId());
                        slWagesDay.setModuleId(rfwork.getModuleId());
                        slWagesDay.setRfworkId(slAttendance.getRfworkId());
                        slWagesDay.setUserName(slAttendance.getUserName());
                        slWagesDay.setNickName(slAttendance.getNickName());
                        slWagesDay.setProDay(slAttendance.getAttendanceDay());
                        slWagesDay.setProSettlement(tmpSettlementDay);
                        slWagesDay.setWagesSacoefficient(tmpCoefficient);
                        slWagesDay.setProWages(BigDecimal.ZERO);
                        slWagesDay.setProDate(rfwork.getRfworkDate());
                        slWagesDay.setWorkType("0");
                        slWagesDayService.insertSlWagesDay(slWagesDay);
                    }
                }
                //鞋面报工单工资平分
                if (rfwork.getModuleId().longValue()==1L){
                    BigDecimal rfworkPay = slRworkService.selectAllPayByRfworkId(rfwork.getRfworkId());
                    //平分工资
                    //基础工资 = 报工单总工资/总出勤结算天数
                    BigDecimal dayBaseWages = rfworkPay.divide(attendanceDay,2,RoundingMode.DOWN).setScale(2,RoundingMode.DOWN);
                    for (SlAttendance slAttendance : slAttendanceList) {
                        //非特殊系数，非小时工，非学徒 更新工资
                        if(slAttendance.getSsmId().longValue() != 4L && slAttendance.getSsmId().longValue() != 5L){
                            if (!ArrayUtil.contains(apprenticeIds, slAttendance.getLevelId()) ) {
                                SlWagesDay slWagesDay = slWagesDayService.selectSlWagesDayByRfworkIdAndUser(slAttendance.getRfworkId(),slAttendance.getUserName());
                                //工资 = 基础工资X出勤天数X工资系数
                                if(StringUtils.isNotNull(slWagesDay)){
                                    slWagesDay.setProWages(dayBaseWages.multiply(slWagesDay.getProDay()).multiply(slWagesDay.getWagesSacoefficient()).setScale(2,RoundingMode.DOWN));
                                    slWagesDayService.updateSlWagesDay(slWagesDay);
                                }
                            }
                        }
                    }
                }
            }

            //单项报工项工资处理及水场工资处理
            List<SlRwork> slRworkList = slRworkService.selectSlRworkListByRfworkId(rfwork.getRfworkId());
            if (StringUtils.isNotEmpty(slRworkList)){
                //获取报工单所有报工项的工序，判断有没有定量
                Map<Long, BigDecimal> tmpMap = new HashMap<>();
                List<SlRwork> groupProcessList = slRworkService.selectGroupProcessByRfworkId(rfwork.getRfworkId());
                for (SlRwork gp :groupProcessList) {
                    SlProcess slProcess = slProcessService.selectSlProcessByProcessId(gp.getProcessId());
                    if (StringUtils.isNotNull(slProcess)){
                        if(slProcess.getQuantify()!=null && slProcess.getQuantify().compareTo(BigDecimal.ZERO)>0 ){
                            if(gp.getRworkActual().compareTo(slProcess.getQuantify())<0){
                                //产量不够，记录工序ID和计算比例
                                BigDecimal bili = gp.getRworkActual().divide(slProcess.getQuantify(),2,RoundingMode.DOWN).setScale(2,RoundingMode.DOWN);
                                tmpMap.put(gp.getProcessId(),bili);
                            }
                        }
                    }
                }

                for (SlRwork rwork:slRworkList) {
                    //单项报工项总工资
                    BigDecimal estimatePay = rwork.getProcessPay().multiply(rwork.getRworkActual()).multiply(BigDecimal.valueOf(rwork.getRworkRepetitions())).setScale(2, RoundingMode.DOWN);
                    //看看在不在定量没达标的列表中,没达标按比例扣减
                    if(StringUtils.isNotEmpty(tmpMap)){
                        if (tmpMap.get(rwork.getProcessId())!=null){
                            estimatePay = estimatePay.multiply(tmpMap.get(rwork.getProcessId())).setScale(2,RoundingMode.DOWN);
                        }
                    }
                    //操作人列表
                    List<SlRworkRmember> memberList = slRworkRmemberService.selectSlRworkRmemberListByRworkId(rwork.getRworkId());
                    //操作人数
                    BigDecimal operatorNumber = BigDecimal.valueOf(memberList.size());
                    //非学徒员工
                    List<SlRworkRmember> nonApprenticeList = new ArrayList<>();

                    if (StringUtils.isNotEmpty(memberList)){
                        for (SlRworkRmember member: memberList) {
                            //学徒可以单独计算工资
                            if (ArrayUtil.contains(apprenticeIds, member.getLevelId())) {
                                //工作时长
                                BigDecimal mduration = member.getRmemberDuration();
                                //支付工资
                                BigDecimal memberPay = BigDecimal.ZERO;
                                //学徒系数
                                SlApprentice slApprentice = new SlApprentice();
                                slApprentice.setModuleId(rfwork.getModuleId());
                                slApprentice.setLevelId(member.getLevelId());
                                slApprentice = slApprenticeService.selectSlApprenticeByModuleAndLevel(slApprentice);
                                if(StringUtils.isNotNull(slApprentice)){
                                    operatorNumber = operatorNumber.subtract(BigDecimal.valueOf(1)).add(slApprentice.getApprenticeDay());
                                    //学徒(正常学徒还是小时工学徒)
                                    if("Y".equals(member.getIsHourlyworker())){
                                        //默认小时工日薪
                                        BigDecimal defaultPay = slWsbase.getScBasepay();

                                        if(rwork.getModuleId().longValue()==3L){
                                            //水场模块下的找对应工序的日薪
                                            SlSa slSa = slSaService.selectSlSaByGprocessId(rwork.getGprocessId());
                                            if (StringUtils.isNotNull(slSa)){
                                                defaultPay = slSa.getSaPay();
                                            }
                                            //水场8-10算1天
                                            if(mduration.compareTo(BigDecimal.valueOf(8))>0 && mduration.compareTo(BigDecimal.valueOf(10))<0){
                                                memberPay = defaultPay;
                                            }else {
                                                memberPay = defaultPay.divide(workHours,2,RoundingMode.DOWN).multiply(mduration).setScale(2, RoundingMode.DOWN);
                                            }
                                        }else{
                                            //非水场按小时
                                            memberPay = defaultPay.divide(workHours,2,RoundingMode.DOWN).multiply(mduration).setScale(2, RoundingMode.DOWN);
                                        }
                                    }else{
                                        //正常学徒
                                        if(rwork.getModuleId().longValue()==3L){
                                            if(mduration.compareTo(BigDecimal.valueOf(8))>0 && mduration.compareTo(BigDecimal.valueOf(10))<0){
                                                memberPay = slApprentice.getApprenticePay().multiply(workHours).setScale(2, RoundingMode.DOWN);
                                            }else {
                                                memberPay = slApprentice.getApprenticePay().multiply(member.getRmemberDuration()).setScale(2, RoundingMode.DOWN);
                                            }
                                        }else {
                                            memberPay = slApprentice.getApprenticePay().multiply(member.getRmemberDuration()).setScale(2, RoundingMode.DOWN);
                                        }
                                    }
                                }
                                //更细操作人工资
                                member.setRmemberPay(memberPay);
                                slRworkRmemberService.updateSlRworkRmember(member);

                                //更新学徒员工报工单工资
                                SlWagesDay slWagesDay = slWagesDayService.selectSlWagesDayByRfworkIdAndUser(rwork.getRfworkId(),member.getRmemberUser());
                                if (StringUtils.isNotNull(slWagesDay)){
                                    slWagesDay.setProWages(slWagesDay.getProWages().add(memberPay));
                                    slWagesDayService.updateSlWagesDay(slWagesDay);
                                }
                            }else{
                                nonApprenticeList.add(member);
                            }

                        }

                        //非学徒员工的特殊系数人员的结算比例
                        if(StringUtils.isNotEmpty(nonApprenticeList)){
                            for (SlRworkRmember rmember:nonApprenticeList) {
                                SlSpecial slSpecial = slSpecialService.selectSlSpecialByUserName(rmember.getRmemberUser());
                                if (StringUtils.isNotNull(slSpecial)){
                                    if(rmember.getSsmId().longValue()==2L || rmember.getSsmId().longValue()==4L){
                                        if("1".equals(slSpecial.getIsProduce())){
                                            operatorNumber = operatorNumber.subtract(BigDecimal.valueOf(1));
                                        }else{
                                            if (slSpecial.getSsScale().compareTo(BigDecimal.valueOf(1))!=0){
                                                operatorNumber = operatorNumber.subtract(BigDecimal.valueOf(1)).add(slSpecial.getSsScale()).setScale(2,RoundingMode.DOWN);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        //非学徒员工计算薪资
                        BigDecimal averagePay = BigDecimal.ZERO;
                        if (operatorNumber.compareTo(BigDecimal.ZERO)>0){
                            averagePay= estimatePay.divide(operatorNumber, 2,RoundingMode.DOWN);
                        }

                        if(StringUtils.isNotEmpty(nonApprenticeList)){
                            for (SlRworkRmember rmember:nonApprenticeList) {
                                //员工出勤工资记录
                                SlWagesDay slWagesDay = slWagesDayService.selectSlWagesDayByRfworkIdAndUser(rwork.getRfworkId(),rmember.getRmemberUser());
                                //结算工资
                                BigDecimal tmpssmpay = averagePay;

                                Long ssmId = rmember.getSsmId();
                                if(ssmId==1){
                                    //固定工资
                                    rmember.setRmemberPay(averagePay);
                                }else if(ssmId==2){
                                    //机台长系数工资，看他和报工人是不是一人，是一人的话按系数算
                                    if(rmember.getRmemberUser().equals(rfwork.getRfworkUser())){
                                        SlSpecial slSpecial = slSpecialService.selectSlSpecialByUserName(rmember.getRmemberUser());
                                        if (StringUtils.isNotNull(slSpecial)){
                                            tmpssmpay = averagePay.multiply(slSpecial.getSsRatio());
                                        }
                                    }else {
                                        slWagesDay.setRfworkssmId(3L);
                                    }
                                    rmember.setRmemberPay(tmpssmpay);
                                    if (rwork.getModuleId().longValue()==3L||rwork.getModuleId().longValue()==2L){
                                        slWagesDay.setProWages(slWagesDay.getProWages().add(tmpssmpay));
                                    }
                                }else if(ssmId==3){
                                    //计件
                                    rmember.setRmemberPay(tmpssmpay);
                                    if (rwork.getModuleId().longValue()==3L||rwork.getModuleId().longValue()==2L){
                                        slWagesDay.setProWages(slWagesDay.getProWages().add(tmpssmpay));
                                    }
                                    //原皮库的存起来最后再算一遍平均的
                                    if(ypkUsers.contains(rmember.getRmemberUser())){
                                        slWagesDay.setIsYpk("0");
                                        ypkDateList.add(rwork.getRworkDate());
                                    }
                                }else if(ssmId==4){
                                    //特殊系数，前面已记录，最后算
                                    //rmember.setRmemberPay(tmpssmpay);
                                }else if(ssmId==5){
                                    //小时工/日工

                                    //小时工默认薪资
                                    BigDecimal defaultPay = slWsbase.getScBasepay();
                                    SlSa slSa = slSaService.selectSlSaByGprocessId(rwork.getGprocessId());
                                    if (StringUtils.isNotNull(slSa)){
                                        defaultPay = slSa.getSaPay();
                                    }
                                    BigDecimal tmpMemberPay = BigDecimal.ZERO;
                                    tmpMemberPay = defaultPay.divide(workHours,2,RoundingMode.DOWN).multiply(rmember.getRmemberDuration()).setScale(2, RoundingMode.DOWN);

                                    if (rwork.getModuleId().longValue()==3L){
                                        if(rmember.getRmemberDuration().compareTo(BigDecimal.valueOf(8))>0 && rmember.getRmemberDuration().compareTo(BigDecimal.valueOf(10))<0){
                                            tmpMemberPay = defaultPay;
                                        }
                                    }
                                    rmember.setRmemberPay(tmpMemberPay);
                                    slWagesDay.setProWages(slWagesDay.getProWages().add(tmpMemberPay).setScale(2, RoundingMode.DOWN));

                                }
                                slRworkRmemberService.updateSlRworkRmember(rmember);
                                if (StringUtils.isNotNull(slWagesDay)){
                                    slWagesDayService.updateSlWagesDay(slWagesDay);
                                }

                            }
                        }
                    }
                }
            }
            rfwork.setIsStatistics("0");    //标记已统计
            slRfworkService.updateSlRfwork(rfwork);

        }
        //特殊系数开始
        if(StringUtils.isNotEmpty(lastAttendance)){
            Map<String ,Set<String >>  alreadyHandle = new HashMap<>();
            for (SlAttendance attendance: lastAttendance) {
                //判断员工对应日期是否已经计算过了
                if(alreadyHandle.containsKey(DateUtils.dateTime(attendance.getRworkDate()))){
                    Set<String> tmpUsers = alreadyHandle.get(DateUtils.dateTime(attendance.getRworkDate()));
                    if(tmpUsers.contains(attendance.getUserName())){
                        continue;
                    }
                }

                //特殊工作规则
                SlSpecial slSpecial = slSpecialService.selectSlSpecialByUserName(attendance.getUserName());
                if (StringUtils.isNotNull(slSpecial)){
                    //按什么平均1模块，2车间，3工序
                    String atype = slSpecial.getAverageType();
                    SlRwork queryRwork = new SlRwork();
                    queryRwork.setRworkDate(attendance.getRworkDate());
                    if("1".equals(atype)){
                        Long moduleId = slSpecial.getModuleId();
                        queryRwork.setModuleId(moduleId);
                    }else if("2".equals(atype)){
                        Long workshopId = slSpecial.getWorkshopId();
                        queryRwork.setWorkshopId(workshopId);
                    }else if("3".equals(atype)){
                        Long gprocessId = slSpecial.getGprocessId();
                        queryRwork.setGprocessId(gprocessId);
                    }
                    //所有包含对应平均的报工单
                    List<Long> rfworkIds = slRworkService.selectGroupRworkByAnyId(queryRwork);
                    int rfworkNum = rfworkIds.size();
                    BigDecimal averagePay = BigDecimal.ZERO;
                    if(StringUtils.isNotEmpty(rfworkIds)){
                        for (Long rfworkid:rfworkIds) {
                            BigDecimal rfworkPay = slRworkService.selectAllPayByRfworkId(rfworkid);
                            BigDecimal settlementDay = slAttendanceService.selectAllSettlementDaysByRfworkId(rfworkid);
                            averagePay =  rfworkPay.divide(settlementDay,2,RoundingMode.DOWN).add(averagePay).setScale(2,RoundingMode.DOWN);
                        }
                    }
                    //指定人的出勤天数
                    BigDecimal usreAttendanceDays = attendance.getAttendanceDay();
                    //报工单总平均工资/报工单数量X个人出勤天数X系数
                    BigDecimal perPay =  averagePay.divide(BigDecimal.valueOf(rfworkNum),2, RoundingMode.DOWN).multiply(usreAttendanceDays).multiply(slSpecial.getSsRatio()).setScale(2, RoundingMode.DOWN);

                    SlWagesDay slWagesDay = slWagesDayService.selectSlWagesDayByRfworkIdAndUser(attendance.getRfworkId(),attendance.getUserName());
                    if (StringUtils.isNull(slWagesDay)){
                        SlWagesDay newSlWagesDay= new SlWagesDay();
                        newSlWagesDay.setLevelId(attendance.getLevelId());
                        newSlWagesDay.setSsmId(attendance.getSsmId());
                        newSlWagesDay.setProSettlement(attendance.getAttendanceDay().multiply(slSpecial.getSsScale()));
                        newSlWagesDay.setWagesSacoefficient(slSpecial.getSsRatio());
                        newSlWagesDay.setUserName(attendance.getUserName());
                        newSlWagesDay.setNickName(attendance.getNickName());
                        newSlWagesDay.setProDate(attendance.getRworkDate());
                        newSlWagesDay.setProDay(attendance.getAttendanceDay());
                        newSlWagesDay.setProWages(perPay);
                        newSlWagesDay.setWorkType("0");
                        slWagesDayService.insertSlWagesDay(newSlWagesDay);
                    }else {
                        slWagesDay.setProWages(perPay);
                        slWagesDayService.updateSlWagesDay(slWagesDay);
                    }
               }


                if(alreadyHandle.containsKey(DateUtils.dateTime(attendance.getRworkDate()))){
                    alreadyHandle.get(DateUtils.dateTime(attendance.getRworkDate())).add(attendance.getUserName());
                }else {
                    Set<String> tmpUsers = new HashSet<>();
                    tmpUsers.add(attendance.getUserName());
                    alreadyHandle.put(DateUtils.dateTime(attendance.getRworkDate()),tmpUsers);
                }
            }
        }

        //原皮库平分开始
        Iterator<Date> ypkIterator = ypkDateList.iterator();
        while(ypkIterator.hasNext()){
            Date ypkDate = ypkIterator.next();
            SlWagesDay slWagesDay = new SlWagesDay();
            slWagesDay.setIsYpk("0");
            slWagesDay.setProDate(ypkDate);
            slWagesDay.setWorkType("0");
            List<SlWagesDay> ypklist =  slWagesDayService.selectSlWagesDayList(slWagesDay);
            if(StringUtils.isNotEmpty(ypklist)){
                //总出勤结算天数
                BigDecimal totalSettlement = BigDecimal.ZERO;
                //总金额
                BigDecimal totalWages = BigDecimal.ZERO;
                for (SlWagesDay wagesDay:ypklist) {
                    totalSettlement = totalSettlement.add(wagesDay.getProSettlement());
                    totalWages = totalWages.add(wagesDay.getProWages());
                }
                //基础金额
                BigDecimal baseWages = totalWages.divide(totalSettlement,2,RoundingMode.DOWN).setScale(2,RoundingMode.DOWN);
                for (SlWagesDay wagesDay:ypklist) {
                    //重新赋值当天工资
                    wagesDay.setProWages(baseWages.multiply(wagesDay.getProSettlement()).setScale(2,RoundingMode.DOWN));
                    slWagesDayService.updateSlWagesDay(wagesDay);
                }
            }
        }


        Set<Date> ypkLgDateList = new HashSet();
        //零工开始
        List<SlRfwork> lgList = slRfworkService.selectAllApprovedSlRfworkList("1");
        for (SlRfwork rfwork : lgList) {
            List<SlOddjobAttendance> slAttendanceList = slOddjobAttendanceService.selectAllSlOddjobAttendanceByRfworkId(rfwork.getRfworkId());
            if(StringUtils.isNotEmpty(slAttendanceList)){
                for (SlOddjobAttendance slAttendance :slAttendanceList) {
                    SlWagesDay slWagesDay = new SlWagesDay();
                    slWagesDay.setRfworkId(rfwork.getRfworkId());
                    slWagesDay.setModuleId(rfwork.getModuleId());
                    slWagesDay.setUserName(slAttendance.getUserName());
                    slWagesDay.setNickName(slAttendance.getNickName());
                    slWagesDay.setProDate(rfwork.getRfworkDate());
                    slWagesDay.setProDay(slAttendance.getAttendanceDay());
                    slWagesDay.setProWages(BigDecimal.ZERO);
                    slWagesDay.setWorkType("1");
                    slWagesDayService.insertSlWagesDay(slWagesDay);
                }
            }
            List<SlOddjob> oddJoblist = slOddjobService.selectSlOddjobListByRfworkId(rfwork.getRfworkId());
            if(StringUtils.isNotEmpty(oddJoblist)){
                for (SlOddjob slOddjob:oddJoblist) {
                    //工作时长
                    BigDecimal duration = slOddjob.getOddjobDuration();
                    //扣款
                    //BigDecimal oddjobDm = slOddjob.getOddjobDm()==null?BigDecimal.ZERO:slOddjob.getOddjobDm();
                    //操作人列表
                    List<SlOddjobOmember> memberList =  slOddjobOmemberService.selectSlOddjobOmemberListByOddjobId(slOddjob.getOddjobId());
                    //计价
                    BigDecimal wmPay =  slOddjob.getWmPay();
                    //单位（1时、2天、3台）
                    String wmUnit = slOddjob.getWmUnit();
                    BigDecimal wages = BigDecimal.ZERO;
                    if("1".equals(wmUnit)){
                        //计价*时长
                        wages = wmPay.multiply(duration).setScale(2, RoundingMode.DOWN);
                    } else if ("2".equals(wmUnit)) {
                        // 计价/10*时长
                        wages = wmPay.divide(workHours,2, RoundingMode.DOWN).multiply(duration).setScale(2, RoundingMode.DOWN);
                    } else if ("3".equals(wmUnit)) {
                        // 计价/人数
                        wages = wmPay.divide(BigDecimal.valueOf(memberList.size()),2, RoundingMode.DOWN).setScale(2, RoundingMode.DOWN);
                    }
                    for (SlOddjobOmember member: memberList) {
                        SlWagesDay slWagesDay = slWagesDayService.selectSlWagesDayByRfworkIdAndUser(rfwork.getRfworkId(),member.getOmemberUser());
                        //扣款
                        //slWagesDay.setProWages(slWagesDay.getProWages().add(wages).subtract(oddjobDm).setScale(2,RoundingMode.DOWN));
                        slWagesDay.setLevelId(member.getLevelId());
                        slWagesDay.setSsmId(member.getSsmId());

                        //学徒系数
                        if (ArrayUtil.contains(apprenticeIds, member.getLevelId())) {
                            SlApprentice slApprentice = new SlApprentice();
                            slApprentice.setModuleId(rfwork.getModuleId());
                            slApprentice.setLevelId(member.getLevelId());
                            slApprentice = slApprenticeService.selectSlApprenticeByModuleAndLevel(slApprentice);
                            BigDecimal tmpWages = wages;
                            if(StringUtils.isNotNull(slApprentice)){
                                tmpWages = slApprentice.getApprenticePay().multiply(duration).setScale(2, RoundingMode.DOWN);
                            }
                            slWagesDay.setProWages(slWagesDay.getProWages().add(tmpWages).setScale(2,RoundingMode.DOWN));

                        }else{
                            slWagesDay.setProWages(slWagesDay.getProWages().add(wages).setScale(2,RoundingMode.DOWN));
                        }


                        //原皮库的存起来最后再算一遍平均的
                        if(ypkUsers.contains(member.getOmemberUser())){
                            slWagesDay.setIsYpk("0");
                            ypkLgDateList.add(rfwork.getRfworkDate());
                        }
                        slWagesDayService.updateSlWagesDay(slWagesDay);
                    }
                }
            }
            rfwork.setIsStatistics("0");    //标记已统计
            slRfworkService.updateSlRfwork(rfwork);

        }
        //原皮库零工开始
        Iterator<Date> ypkLgIterator = ypkLgDateList.iterator();
        while(ypkLgIterator.hasNext()){
            Date ypkDate = ypkLgIterator.next();
            SlWagesDay slWagesDay = new SlWagesDay();
            slWagesDay.setIsYpk("0");
            slWagesDay.setProDate(ypkDate);
            slWagesDay.setWorkType("1");
            List<SlWagesDay> ypklist =  slWagesDayService.selectSlWagesDayList(slWagesDay);
            if(StringUtils.isNotEmpty(ypklist)){
                //总出勤结算天数
                BigDecimal totalProday = BigDecimal.ZERO;
                //总金额
                BigDecimal totalWages = BigDecimal.ZERO;
                for (SlWagesDay wagesDay:ypklist) {
                    totalProday = totalProday.add(wagesDay.getProDay());
                    totalWages = totalWages.add(wagesDay.getProWages());
                }
                //基础金额
                BigDecimal baseWages = totalWages.divide(totalProday,2,RoundingMode.DOWN).setScale(2,RoundingMode.DOWN);
                for (SlWagesDay wagesDay:ypklist) {
                    //重新赋值当天工资
                    wagesDay.setProWages(baseWages.multiply(wagesDay.getProDay()).setScale(2,RoundingMode.DOWN));
                    slWagesDayService.updateSlWagesDay(wagesDay);
                }
            }
        }
        System.out.println("end------------车间日工资计算结束--------------");
    }

}
